/*
 * Copyright 2009 Andreas Borglin andreas.borglin@gmail.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package borge.mobile.app.jakoon;

import borge.mobile.app.jakoon.Main.ESwtExecutor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Text;

/**
 * Form used when user wants to save image
 * @author Andreas Borglin
 */
public class SaveForm {

    private Composite parent;
    private Composite top;
    private Composite saveComp;
    private Composite commandComp;
    private ESwtExecutor executor;

    private Combo outputFormats;
    private Button fileOverwrite;
    private Text dirText;
    private Text fileText;
    private Text sizeText;
    private String[] formats;
    
    private static final int NUM_COLUMNS = 2;
    
    class SaveData {
        
        public String directory;
        public String filename;
        public boolean overwrite;
        public String format;
        public boolean inPercent;
        public int sizeValOne;
        public int sizeValTwo;
        
    }

    protected SaveForm(ESwtExecutor exec, Composite parent) {

        this.parent = parent;
        executor = exec;

        top = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.numColumns = 1;
        top.setLayout(layout);
        
        saveComp = new Composite(top, SWT.NONE);
        layout = new GridLayout();
        layout.marginLeft = 20;
        layout.numColumns = NUM_COLUMNS;
        saveComp.setLayout(layout);
        
        commandComp = new Composite(top, SWT.NONE);
        layout = new GridLayout();
        layout.numColumns = 2;
        layout.marginLeft = 480;
        commandComp.setLayout(layout);

        // Title, centered and spawns over all columns
        Label title = new Label(saveComp, SWT.NONE);
        title.setText("Save image");
        GridData data = new GridData();
        data.horizontalAlignment = GridData.CENTER;
        data.horizontalSpan = NUM_COLUMNS;
        data.heightHint = 40;
        title.setLayoutData(data);

        initDirectoryArea();
        initFileArea();
        initFormatsArea();
        initCommandsArea();

        saveComp.layout();
        commandComp.layout();
        top.layout();

    }

    protected void makeVisible(){
        top.setVisible(true);
    }
    
    protected void setOutputFormats(String[] formats){
        this.formats = formats;
        
        outputFormats.removeAll();
        
        for(int i = 0; i < formats.length; ++i){
            if(!formats[i].equalsIgnoreCase("image/raw"))
                outputFormats.add(formats[i]);
        }
        outputFormats.select(0);
    }
    
    protected void setDirAndFile(String dir, String file){
        dirText.setText(dir);
        fileText.setText(file);
    }

    private void initDirectoryArea() {
        
        GridData data;
        
        // Directory stuff
        Label dirLabel = new Label(saveComp, SWT.NONE);
        dirLabel.setText("Directory");
        data = new GridData();
        data.horizontalAlignment = GridData.BEGINNING;
        data.horizontalSpan = NUM_COLUMNS;
        dirLabel.setLayoutData(data);

        dirText = new Text(saveComp, SWT.SINGLE);
        dirText.setText("Unknown");
        data = new GridData();
        data.widthHint = 300;
        dirText.setLayoutData(data);

        Button dirBrowse = new Button(saveComp, SWT.PUSH);
        dirBrowse.setText("Browse");
        dirBrowse.addSelectionListener(new SelectionListener() {
            public void widgetDefaultSelected(SelectionEvent event) {}
            public void widgetSelected(SelectionEvent event) {
                DirectoryDialog dd = new DirectoryDialog(executor.getShell(), SWT.OPEN);
                dd.setMessage("Choose image save path");
                String dir = dd.open();
                if(dir != null)
                    dirText.setText(dir);
            }
        });

        data = new GridData();
        data.horizontalAlignment = GridData.BEGINNING;
        data.horizontalSpan = NUM_COLUMNS-1;
        dirBrowse.setLayoutData(data);
    }

    private void initFileArea() {
        
        GridData data;
        
        Label fileLabel = new Label(saveComp, SWT.NONE);
        fileLabel.setText("Filename");
        data = new GridData();
        data.horizontalAlignment = GridData.BEGINNING;
        data.horizontalSpan = NUM_COLUMNS;
        fileLabel.setLayoutData(data);

        fileText = new Text(saveComp, SWT.SINGLE);
        fileText.setText("Unknown");
    
        data = new GridData();
        data.widthHint = 300;
        data.grabExcessHorizontalSpace = true;
        fileText.setLayoutData(data);

        fileOverwrite = new Button(saveComp, SWT.CHECK);
        fileOverwrite.setText("Overwrite");
        data = new GridData();
        data.horizontalAlignment = GridData.BEGINNING;
        data.horizontalSpan = NUM_COLUMNS-1;
        fileOverwrite.setLayoutData(data);
    }

    private void initFormatsArea() {
        
        GridData data;
        
        Label outputLabel = new Label(saveComp, SWT.NONE);
        outputLabel.setText("Output format");
        data = new GridData();
        data.horizontalAlignment = GridData.BEGINNING;
        data.horizontalSpan = 1;
        outputLabel.setLayoutData(data);
        
        Label sizeLabel = new Label(saveComp, SWT.NONE);
        sizeLabel.setText("Output size");
        data = new GridData();
        data.horizontalAlignment = GridData.BEGINNING;
        data.horizontalSpan = 1;
        sizeLabel.setLayoutData(data);

        outputFormats = new Combo(saveComp, SWT.NONE);
        outputFormats.add("Original");
        
        if(formats != null){
            for (int i = 0; i < formats.length; ++i) {
                outputFormats.add(formats[i]);
            }
        }
        outputFormats.select(0);

        data = new GridData();
        data.horizontalAlignment = GridData.BEGINNING;
        data.horizontalSpan = 1;
        outputFormats.setLayoutData(data);
        
        sizeText = new Text(saveComp, SWT.NONE);
        sizeText.setText("100%");
        data = new GridData();
        data.horizontalAlignment = GridData.FILL;
        sizeText.setLayoutData(data);
    }

    private void initCommandsArea() {
        
        GridData data;
        
        Button save = new Button(commandComp, SWT.PUSH);
        save.setText("Save");
        save.addSelectionListener(new SelectionListener() {
            public void widgetDefaultSelected(SelectionEvent event) {}
            public void widgetSelected(SelectionEvent event) {
                save();
            }
        });

        data = new GridData();
        save.setLayoutData(data);

        Button back = new Button(commandComp, SWT.PUSH);
        back.setText("Back");
        back.addSelectionListener(new SelectionListener() {
            public void widgetDefaultSelected(SelectionEvent event) {}
            public void widgetSelected(SelectionEvent event) {
                top.setVisible(false);
                executor.loadImageForm(false);
            }
        });
        
        data = new GridData();
        back.setLayoutData(data);
    }

    private void save() {

        String dir = dirText.getText();
        String filename = fileText.getText();
        boolean overwrite = fileOverwrite.getSelection();
        String outputformat = outputFormats.getItem(outputFormats.getSelectionIndex());
        String size = sizeText.getText();
        SaveData data = new SaveData();
        if(!verifySize(size, data)){
            // show error
            MessageBox mb = new MessageBox(executor.getShell(), SWT.ICON_ERROR);
            mb.setMessage("Output size can be in either absolute values or percent.\n " +
                    "Absolute format (>0): 1234x2345\nPercent format (1-100): 90%");
            mb.open();
            return;
        }
        
        data.directory = dir;
        data.filename = filename;
        data.overwrite = overwrite;
        data.format = outputformat;
        top.setVisible(false);
        executor.saveImage(data);
    }
    
    private boolean verifySize(String size, SaveData data){
        
        size = size.toLowerCase().trim();
        
        if(size.endsWith("%")){
            
            String percent = size.substring(0, size.length()-1);
            try{
               int value = Integer.parseInt(percent);
               if(value < 0 || value > 100){
                   throw new Exception();
               }
               
               data.sizeValOne = value;
               data.inPercent = true;
            }
            catch(Exception e){
                return false;
            }
        }
        else if(size.indexOf("x") != -1){
            int pos = size.indexOf("x");
            String width = size.substring(0, pos);
            String height = size.substring(pos+1, size.length());
            
            try{
                
                int wvalue = Integer.parseInt(width);
                int hvalue = Integer.parseInt(height);
                
                if(wvalue < 1 || hvalue < 1 || wvalue >= 10000 || hvalue >= 10000)
                    throw new Exception();
                
                data.sizeValOne = wvalue;
                data.sizeValTwo = hvalue;
                data.inPercent = false;
                
            }
            catch(Exception e){
                return false;
            }
            
        }
        else{
            return false;
        }
        
        return true;
        
    }
}
